// PathManager.ts
import { _decorator, Component, v2, Vec2, Vec3 } from 'cc';
const { ccclass } = _decorator;

@ccclass('PathManager')
export class PathManager extends Component {
    private static _instance: PathManager;
    private _segments: Vec2[][] = [];
    public static equidistantPoints: Vec2[] = [];
    private _diameter: number = 0;

    public static get Instance(): PathManager {
        if (!this._instance) {
            this._instance = new PathManager();
        }
        return this._instance;
    }

    /**
     * 初始化路径数据并生成等距点
     * @param pathData 贝塞尔曲线数据（每个段落3个点）
     * @param diameter 小球直径（点间距）
     */
    public init(pathData: Vec2[][], diameter: number) {
        this._segments = pathData;
        this._diameter = diameter;
        this._generateEquidistantPoints();
    }

    /**
     * 获取起始点
     * @returns 起始点
     */
    public getStartPoint(): Vec3 {
        return new Vec3(PathManager.equidistantPoints[0].x, PathManager.equidistantPoints[0].y, 0);
        return new Vec3(this._segments[0][0].x, this._segments[0][0].y, 0);
    }


    private _generateEquidistantPoints() {
        PathManager.equidistantPoints = [];
        if (!this._validateData()) return;

        // 预计算全路径的采样点
        const pathSamples: { point: Vec2, cumulativeLength: number }[] = [];
        let totalLength = 0;

        // 遍历所有贝塞尔段
        this._segments.forEach((segment, index) => {
            const [P0, P1, P2] = segment;
            
            // 添加首段的起点
            if (index === 0) {
                pathSamples.push({ 
                    point: new Vec2(P0), 
                    cumulativeLength: 0 
                });
            }

            // 生成当前段的采样点
            const segmentSamples = this._sampleBezierSegment(
                P0, P1, P2, 
                index > 0 // 非首段跳过第一个采样点（避免重复）
            );

            // 合并采样点并计算累积长度
            segmentSamples.forEach(sample => {
                totalLength += sample.distance;
                pathSamples.push({
                    point: sample.point,
                    cumulativeLength: totalLength
                });
            });
        });

        // 生成等距点
        const stepCount = Math.floor(totalLength / this._diameter);
        for (let i = 1; i <= stepCount; i++) {
            const targetLength = i * this._diameter;
            const point = this._findPointAtDistance(pathSamples, targetLength);
            if (point) PathManager.equidistantPoints.push(point);
        }
    }

    // 贝塞尔曲线采样（返回相对移动距离）
    private _sampleBezierSegment(
        P0: Vec2,
        P1: Vec2,
        P2: Vec2,
        skipFirst: boolean
    ): { point: Vec2, distance: number }[] {
        const samples: { point: Vec2, distance: number }[] = [];
        const SAMPLE_STEPS = 100; // 每段采样100次
        
        let previousPoint = new Vec2(P0);
        let startStep = skipFirst ? 1 : 0; // 跳过第一个样本

        for (let step = startStep; step <= SAMPLE_STEPS; step++) {
            const t = step / SAMPLE_STEPS;
            const currentPoint = this._calculateBezierPoint(t, P0, P1, P2);
            
            if (step > 0) { // 计算与前一点的间距
                const distance = Vec2.distance(previousPoint, currentPoint);
                samples.push({
                    point: currentPoint.clone(),
                    distance: distance
                });
            }
            previousPoint = currentPoint;
        }
        return samples;
    }

    // 计算二次贝塞尔曲线点
    private _calculateBezierPoint(t: number, P0: Vec2, P1: Vec2, P2: Vec2): Vec2 {
        const u = 1 - t;
        return new Vec2(
            u * u * P0.x + 2 * u * t * P1.x + t * t * P2.x,
            u * u * P0.y + 2 * u * t * P1.y + t * t * P2.y
        );
    }

    // 二分查找目标距离对应的点
    private _findPointAtDistance(
        samples: { point: Vec2, cumulativeLength: number }[],
        target: number
    ): Vec2 | null {
        let left = 0;
        let right = samples.length - 1;

        // 边界检查
        if (target <= 0) return samples[0].point.clone();
        if (target >= samples[right].cumulativeLength) return null;

        // 二分查找
        while (left <= right) {
            const mid = Math.floor((left + right) / 2);
            if (samples[mid].cumulativeLength < target) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }

        // 线性插值
        const before = samples[left - 1];
        const after = samples[left];
        const t = (target - before.cumulativeLength) / 
                 (after.cumulativeLength - before.cumulativeLength);
        
        return new Vec2(
            before.point.x + (after.point.x - before.point.x) * t,
            before.point.y + (after.point.y - before.point.y) * t
        );
    }

    // 数据校验
    private _validateData(): boolean {
        return this._segments.length > 0 &&
               this._diameter > 0 &&
               this._segments.every(s => s.length === 3);
    }

    // 保持原有方法
    public getSegments(): Vec2[][] { return this._segments; }
    public getSegmentCount(): number { return this._segments.length; }

}